﻿using System;
using System.IO.Ports;

namespace SksApp
{
    public class Display
    {
        private static Display _instance;
        private Display() { }
        public static Display Get
        {
            get
            {
                if (_instance == null)
                    _instance = new Display();
                return _instance;
            }
        }

        protected const byte Off = 0x00,
                      On = 0x01,
                      Warning = 0x07,
                      CursorMoveLeft = 0x08,
                      CursorMoveRight = 0x09,
                      CursorMoveDown = 0x0A,
                      CursorHome = 0x0B,
                      ClrScreen = 0x0C,
                      BothDisplays = 0x1A,
                      CustomerDisplayOnly = 0x1C,
                      CashierDisplayOnly = 0x1D,
                      ClearWarning = 0x1E,
                      Initialize = 0x1F,
                      Space = 0x20,
                      InitScreen = 0x28;

        protected readonly byte[] normalMode = { ClrScreen, Initialize, 0x01 };
        protected readonly byte[] verticalScrollMode = { ClrScreen, Initialize, 0x02 };
        protected readonly byte[] horizontalScrollMode = { ClrScreen, Initialize, 0x03 };
        protected readonly byte[] initializeDisplay = { ClrScreen, CursorHome };

        SerialPort serialPort = null;
        public Display(String portName)
        {
            try
            {
                serialPort = new SerialPort(portName);
                if (!serialPort.IsOpen)
                {
                    //serialPort.ReadTimeout = 2048;
                    serialPort.Open();
                    //serialPort.Write(initializeDisplay, 0, 2);
                    serialPort.Write(horizontalScrollMode, 0, horizontalScrollMode.Length);
                    System.Threading.Thread.Sleep(100);
                    //serialPort.Write(normalMode, 0, normalMode.Length);
                }
            }
            catch (UnauthorizedAccessException ex)
            {
                throw ex;
            }
            catch
            { }
        }


        public void WriteFirstLine(String message)
        {
            if (message.Length > 20)
                message = message.Substring(0, 20);
            if (serialPort.IsOpen)
            {
                serialPort.Write(new byte[] { CursorHome }, 0, 1);
                serialPort.Write(FixTurkish(message), 0, message.Length);
            }
        }
        public void WriteSecondLine(String message)
        {
            if (message.Length > 20)
                message = message.Substring(0, 20);
            else
                message = message.PadLeft(20);

            if (serialPort.IsOpen)
            {
                serialPort.Write(new byte[] { CursorHome, CursorMoveDown }, 0, 2);
                serialPort.Write(FixTurkish(message), 0, message.Length);
            }
        }

        private byte[] FixTurkish(String s)
        {
            byte[] b = new byte[s.Length + 2];
            int i = 0;
            foreach (char c in s)
            {
                switch ((int)c)
                {
                    case 286: //G.
                        b[i++] = 166;
                        break;
                    case 287: //g.
                        b[i++] = (byte)'g';
                        break;
                    case 220: //U.
                        b[i++] = 154;
                        break;
                    case 252: //u:
                        goto case 220;
                    case 350: //S.
                        b[i++] = 158;
                        break;
                    case 351: //s.
                        b[i++] = (byte)'s';
                        break;
                    case 304: //I.
                        b[i++] = 152;
                        break;
                    case 305: //i no .
                        b[i++] = (byte)'i';
                        break;
                    case 199: //C.
                        b[i++] = 128;
                        break;
                    case 214: //O:
                        b[i++] = 153;
                        break;
                    case 231: //c.
                        b[i++] = (byte)'c';
                        break;
                    case 246: //o:
                        b[i++] = 153;
                        break;
                    default:
                        b[i++] = (byte)c;
                        break;

                }
            }
            b[s.Length] = CursorHome;
            b[s.Length + 1] = CursorMoveDown;
            return b;
        }

        internal void Disconnect()
        {
            if (serialPort != null)
                serialPort.Close();
        }
    }
}
